import React, { useMemo, useEffect } from "react";
import { addDays, format, differenceInDays, isValid, parseISO } from "date-fns";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip as RechartsTooltip,
  Legend,
  ResponsiveContainer,
} from "recharts";
import { Calendar, GanttChartSquare, AlertCircle } from "lucide-react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

export default function SchedulePlanner({
  scheme,
  onUpdate,
  onScheduledStepsChange,
  hasCycle,
  stepsUpdateCount,
}) {
  // 核心优化：统一前置步骤与步骤编号的类型（都转为字符串进行比较）
  const normalizeValue = (value) => {
    // 处理null/undefined
    if (value == null) return "";
    // 统一转为字符串进行比较（避免数字1和字符串"1"不匹配的问题）
    return String(value).trim();
  };

  const { scheduledSteps, totalDuration, projectStartDate, error } =
    useMemo(() => {
      if (hasCycle) {
        return {
          scheduledSteps: [],
          totalDuration: 0,
          projectStartDate: null,
          error: "检测到循环依赖关系，无法生成进度计划。",
        };
      }

      // 检查开始日期
      const startDate = scheme.constructionStartDate
        ? parseISO(scheme.constructionStartDate)
        : null;
      
      if (!startDate || !isValid(startDate)) {
        return {
          scheduledSteps: [],
          totalDuration: 0,
          projectStartDate: null,
          error: "请先设置有效的“计划施工开始日期”（格式：YYYY-MM-DD）。",
        };
      }

      // 检查步骤是否存在
      const steps = scheme.constructionSteps || [];
      if (steps.length === 0) {
        return {
          scheduledSteps: [],
          totalDuration: 0,
          projectStartDate: startDate,
          error: "请先添加至少一个施工步骤。",
        };
      }

      // 标准化所有步骤编号（转为字符串）
      const normalizedStepOrders = steps.map(s => normalizeValue(s.stepOrder));
      const stepOrderMap = new Map(
        steps.map(s => [normalizeValue(s.stepOrder), s.stepOrder])
      );

      // 检查步骤编号重复
      if (new Set(normalizedStepOrders).size !== normalizedStepOrders.length) {
        return {
          scheduledSteps: [],
          totalDuration: 0,
          projectStartDate: startDate,
          error: "存在重复的步骤编号，请修改为唯一编号。",
        };
      }

      // 检查前置步骤引用（核心优化点）
      const invalidPredecessors = [];
      steps.forEach(step => {
        const currentStepOrder = normalizeValue(step.stepOrder);
        const predecessors = step.predecessorSteps || [];

        predecessors.forEach(pred => {
          const normalizedPred = normalizeValue(pred);
          // 检查前置步骤是否存在于步骤列表中
          if (!normalizedStepOrders.includes(normalizedPred)) {
            invalidPredecessors.push({
              step: stepOrderMap.get(currentStepOrder), // 显示原始步骤编号
              invalidPred: pred // 显示用户输入的原始值
            });
          }
        });
      });

      if (invalidPredecessors.length > 0) {
        const errorDetails = invalidPredecessors.map(item => 
          `步骤 ${item.step} 引用了不存在的前置步骤 "${item.invalidPred}"`
        ).join('；');
        
        return {
          scheduledSteps: [],
          totalDuration: 0,
          projectStartDate: startDate,
          error: `存在无效的前置步骤引用：${errorDetails}。`,
        };
      }

      // 初始化步骤映射表（使用标准化编号作为键）
      let stepMap = new Map(
        steps.map((s) => [
          normalizeValue(s.stepOrder),
          { ...s, startDate: null, endDate: null },
        ])
      );
      let scheduledCount = 0;
      let iterations = 0;
      const maxIterations = steps.length * 2;

      // 调度算法（使用标准化编号查找前置步骤）
      while (scheduledCount < steps.length && iterations < maxIterations) {
        let scheduledThisLoop = false;
        
        for (const step of steps) {
          const stepKey = normalizeValue(step.stepOrder);
          const currentStep = stepMap.get(stepKey);
          if (currentStep.startDate) continue;

          let allPredecessorsScheduled = true;
          let latestPredecessorEndDate = startDate;
          const predecessors = step.predecessorSteps || [];

          if (predecessors.length > 0) {
            for (const pred of predecessors) {
              const predKey = normalizeValue(pred);
              const predStep = stepMap.get(predKey);
              
              if (!predStep || !predStep.endDate) {
                allPredecessorsScheduled = false;
                break;
              }
              
              if (predStep.endDate > latestPredecessorEndDate) {
                latestPredecessorEndDate = predStep.endDate;
              }
            }
          }

          if (allPredecessorsScheduled) {
            currentStep.startDate = predecessors.length 
              ? addDays(latestPredecessorEndDate, 1) 
              : startDate;
              
            currentStep.endDate = addDays(
              currentStep.startDate,
              (step.durationDays || 1) - 1
            );
            
            scheduledCount++;
            scheduledThisLoop = true;
          }
        }

        iterations++;
        if (!scheduledThisLoop) break;
      }

      // 检查未调度的步骤
      const unScheduled = Array.from(stepMap.values())
        .filter(step => !step.startDate)
        .map(step => step.stepOrder);

      if (scheduledCount < steps.length) {
        return {
          scheduledSteps: [],
          totalDuration: 0,
          projectStartDate: startDate,
          error: `无法调度所有步骤，未调度的步骤：${unScheduled.join(', ')}`,
        };
      }

      // 计算总工期
      const finalSteps = Array.from(stepMap.values());
      const maxEndDate = finalSteps.reduce(
        (max, step) => (!max || step.endDate > max) ? step.endDate : max,
        null
      );
      const duration = maxEndDate
        ? differenceInDays(maxEndDate, startDate) + 1
        : 0;

      return {
        scheduledSteps: finalSteps.sort((a, b) => a.stepOrder - b.stepOrder),
        totalDuration: duration,
        projectStartDate: startDate,
        error: null,
      };
    }, [
      scheme.constructionSteps, 
      scheme.constructionStartDate, 
      hasCycle, 
      stepsUpdateCount,
      // 新增：当步骤的前置步骤变化时强制重新计算
      JSON.stringify(scheme.constructionSteps?.map(s => s.predecessorSteps))
    ]);

  // 同步更新逻辑
  useEffect(() => {
    if (onScheduledStepsChange && !error) {
      onScheduledStepsChange(scheduledSteps);
    }
  }, [scheduledSteps, onScheduledStepsChange, error]);

  useEffect(() => {
    if (totalDuration > 0 && scheme.totalDuration !== totalDuration) {
      onUpdate({ totalDuration: totalDuration });
    }
  }, [totalDuration, onUpdate, scheme.totalDuration]);

  // 甘特图数据
  const ganttData = useMemo(() => {
    if (!projectStartDate || !scheduledSteps.length) return [];
    return scheduledSteps
      .map((step) => ({
        name: `${step.stepOrder}. ${step.stepName}`,
        start: step.startDate ? differenceInDays(step.startDate, projectStartDate) : 0,
        duration: step.durationDays || 1,
      }))
      .sort((a, b) => b.start - a.start);
  }, [scheduledSteps, projectStartDate]);

  // 甘特图提示框
  const CustomGanttTooltip = ({ active, payload }) => {
    if (active && payload?.[0]?.payload && projectStartDate) {
      const data = payload[0].payload;
      const startDisplayDate = addDays(projectStartDate, data.start);
      const endDisplayDate = addDays(startDisplayDate, data.duration - 1);
      
      return (
        <div className="bg-white p-3 border rounded shadow-lg text-sm">
          <p className="font-bold mb-1">{data.name}</p>
          <p>开始日期: {format(startDisplayDate, "yyyy-MM-dd")}</p>
          <p>结束日期: {format(endDisplayDate, "yyyy-MM-dd")}</p>
          <p>工期: {data.duration} 天</p>
        </div>
      );
    }
    return null;
  };

  if (error) {
    return (
      <Alert variant="destructive" className="mb-4">
        <AlertCircle className="h-4 w-4" />
        <AlertTitle>无法生成进度计划</AlertTitle>
        <AlertDescription>
          {error}
          <div className="mt-2 text-sm">
            提示：请确保前置步骤的编号与已存在的步骤编号完全匹配（包括类型和格式）。
          </div>
        </AlertDescription>
      </Alert>
    );
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <GanttChartSquare className="w-5 h-5 text-blue-600" />
          进度计划
        </CardTitle>
        <CardDescription>
          总工期估算: <Badge variant="secondary">{totalDuration} 天</Badge>
          {projectStartDate && (
            <>，计划开始日期: <Badge variant="outline">{format(projectStartDate, "yyyy-MM-dd")}</Badge></>
          )}
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        <Tabs defaultValue="table" className="w-full">
          <TabsList className="grid w-full grid-cols-2">
            <TabsTrigger value="table">计划详情表</TabsTrigger>
            <TabsTrigger value="gantt">进度甘特图</TabsTrigger>
          </TabsList>
          <TabsContent value="table" className="mt-4">
            <div className="border rounded-md overflow-x-auto">
              <Table>
                <TableHeader className="sticky top-0 bg-white z-10">
                  <TableRow>
                    <TableHead>步骤</TableHead>
                    <TableHead>工作内容</TableHead>
                    <TableHead>工期(天)</TableHead>
                    <TableHead>前置步骤</TableHead>
                    <TableHead>开始日期</TableHead>
                    <TableHead>结束日期</TableHead>
                    <TableHead>备注</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {scheduledSteps.map((step) => (
                    <TableRow key={step.stepOrder} className="hover:bg-gray-50">
                      <TableCell>{step.stepOrder}</TableCell>
                      <TableCell className="font-medium">
                        <div className="max-w-md truncate" title={step.stepName}>
                          {step.stepName}
                        </div>
                      </TableCell>
                      <TableCell>{step.durationDays || 1}</TableCell>
                      <TableCell>
                        <div className="truncate" title={step.predecessorSteps?.join(", ") || "无"}>
                          {step.predecessorSteps?.length 
                            ? step.predecessorSteps.join(", ") 
                            : "无"}
                        </div>
                      </TableCell>
                      <TableCell>{step.startDate && format(step.startDate, "yyyy-MM-dd")}</TableCell>
                      <TableCell>{step.endDate && format(step.endDate, "yyyy-MM-dd")}</TableCell>
                      <TableCell>
                        <div className="truncate" title={step.remark || ""}>
                          {step.remark || "-"}
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          </TabsContent>
          <TabsContent value="gantt" className="mt-4">
            <div className="h-[600px] w-full bg-gray-50/50 p-4 rounded-lg border">
              <ResponsiveContainer width="100%" height="100%">
                <BarChart
                  data={ganttData}
                  layout="vertical"
                  margin={{ top: 5, right: 30, left: 120, bottom: 20 }}
                >
                  <CartesianGrid strokeDasharray="3 3" />
                  <XAxis
                    type="number"
                    domain={[0, (dataMax) => Math.ceil((dataMax + 2) / 5) * 5]}
                    label={{ value: "天数 (从项目开始计)", position: "insideBottom", offset: -10 }}
                  />
                  <YAxis dataKey="name" type="category" width={120} tick={{ fontSize: 12 }} interval={0} />
                  <RechartsTooltip content={<CustomGanttTooltip />} cursor={{ fill: "rgba(200, 200, 200, 0.1)" }} />
                  <Legend verticalAlign="top" wrapperStyle={{ paddingBottom: "15px" }} />
                  <Bar dataKey="start" stackId="a" fill="transparent" legendType="none" />
                  <Bar dataKey="duration" stackId="a" fill="#3b82f6" name="工期" radius={[0, 4, 4, 0]} />
                </BarChart>
              </ResponsiveContainer>
            </div>
          </TabsContent>
        </Tabs>
      </CardContent>
    </Card>
  );
}
    